<template>
  <view class="carousel" :class="{ 'loading': loading }">
    <!-- 主轮播图 -->
    <swiper 
      class="swiper-container" 
      :autoplay="true" 
      :interval="4000" 
      :circular="true" 
      :indicator-dots="false"
      :duration="600"
      @change="handleChange"
      @animationfinish="handleAnimationFinish">
      <swiper-item v-for="(banner, index) in banners" :key="banner.id" class="swiper-item">
        <view class="banner-wrapper" :class="{ 'active': currentIndex === index }">
          <image 
            :src="banner.image" 
            mode="aspectFill" 
            class="banner-img"
            @load="handleImageLoad(index)"
            @error="handleImageError(index, banner)" />
          
          <!-- 渐变遮罩 -->
          <view class="gradient-overlay"></view>
          
          <!-- 文本内容 -->
          <view class="banner-content" :class="{ 'active': currentIndex === index }">
            <text class="banner-title">{{ banner.title }}</text>
            <text class="banner-desc">{{ banner.desc }}</text>
          </view>
        </view>
      </swiper-item>
    </swiper>

    <!-- 自定义指示器 -->
    <view class="custom-indicators">
      <view 
        v-for="(banner, index) in banners" 
        :key="banner.id"
        class="indicator-dot"
        :class="{ 'active': currentIndex === index }"
        @click="handleIndicatorClick(index)">
        <view class="indicator-inner"></view>
      </view>
    </view>

    <!-- 错误提示 -->
    <view v-if="error" class="carousel-error">{{ error }}</view>
  </view>
</template>

<script>
import config from '@/config.js';

export default {
  name: 'Carousel',
  data() {
    return {
      currentIndex: 0,
      imagesLoaded: new Set(),
      banners: [],
      loading: false,
      error: null,
      loadTimeouts: {}, // 新增:图片加载超时管理
      retryCount: 0,    // 新增:重试计数
      maxRetries: 3,     // 新增:最大重试次数
      socketTask: null,
    };
  },
  created() {
    this.connectWebSocket();
    this.getCarouselList();
  },
  beforeDestroy() {
    if (this.socketTask) {
      this.socketTask.close();
    }
  },
  methods: {
    connectWebSocket() {
      // 建立 WebSocket 连接
      this.socketTask = uni.connectSocket({
        url: `ws://${config.baseURL.replace(/^https?:\/\//, '')}/websocket/carousel`,
        complete: () => {}
      });
      
      // 监听连接成功
      this.socketTask.onOpen(() => {
        console.log('WebSocket连接成功');
      });
      
      // 监听服务器消息
      this.socketTask.onMessage((res) => {
        console.log('收到服务器消息：', res.data);
        if (res.data === 'CAROUSEL_UPDATE') {
          this.getCarouselList(); // 自动刷新数据
        }
      });
      
      // 监听错误
      this.socketTask.onError((res) => {
        console.error('WebSocket连接错误：', res);
      });
      
      // 监听连接关闭
      this.socketTask.onClose(() => {
        console.log('WebSocket连接已关闭');
        // 可以在这里添加重连逻辑
        setTimeout(() => {
          this.connectWebSocket();
        }, 3000);
      });
    },
    
    getImageUrl(path) {
      if (!path) return '';
      if (path.startsWith('http')) return path;
      
      // 直接使用完整的baseURL和路径
      return `${config.baseURL}${path}`;
    },
    
    async getCarouselList() {
      if (this.loading) return;
      this.loading = true;
      this.error = null;
      
      try {
        const res = await uni.request({
          url: '/api/carousel/list',
          method: 'GET',
          header: {
            'Content-Type': 'application/json'
          }
        });
        
        if (res.statusCode === 200 && res.data.success) {
          const carouselList = res.data.data;
          if (Array.isArray(carouselList) && carouselList.length > 0) {
            this.banners = carouselList
              .filter(item => item.status === 1)
              .sort((a, b) => a.sort - b.sort)
              .map(item => ({
                id: item.id,
                image: this.getImageUrl(item.imageUrl),
                title: item.title,
                desc: item.desc,
                link: item.link || '#'
              }));
          } else {
            this.error = '暂无轮播图数据';
          }
        } else {
          this.error = res.data.message || '获取数据失败';
        }
      } catch(e) {
        console.error('获取轮播图失败:', e);
        this.error = '网络请求失败，请检查网络连接';
      } finally {
        this.loading = false;
      }
    },
    
    handleChange(e) {
      this.currentIndex = e.detail.current;
    },
    handleAnimationFinish() {
      // 动画完成后的处理
    },
    handleImageLoad(index) {
      this.imagesLoaded.add(index);
      // 所有图片加载完成后的处理
      if (this.imagesLoaded.size === this.banners.length) {
        this.loading = false;
      }
    },
    handleIndicatorClick(index) {
      this.currentIndex = index;
    },
    handleImageError(index, banner) {
      console.error(`图片加载失败 [${index}]:`, banner.image);
    }
  }
};
</script>

<style scoped>
.carousel {
  position: relative;
  width: 100%;
  height: 400rpx;
  margin: 20rpx 0;
}

.carousel.loading {
  position: relative;
}

.carousel.loading::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(255, 255, 255, 0.1);
  backdrop-filter: blur(4px);
  z-index: 2;
  opacity: 1;
  transition: opacity 0.3s;
}

/* 添加错误提示样式 */
.carousel-error {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  color: #ff4d4f;
  font-size: 28rpx;
  z-index: 3;
  text-align: center;
  background: rgba(255, 255, 255, 0.9);
  padding: 20rpx 40rpx;
  border-radius: 8rpx;
}

.swiper-container {
  width: 100%;
  height: 100%;
  border-radius: 24rpx;
  overflow: hidden;
  transform: translateZ(0);
  box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.12);
}

.swiper-item {
  position: relative;
  width: 100%;
  height: 100%;
}

.banner-wrapper {
  position: relative;
  width: 100%;
  height: 100%;
  overflow: hidden;
}

.banner-img {
  width: 100%;
  height: 100%;
  transition: all 0.6s ease-out;
  transform: scale(1.05);
  object-fit: cover;
}

.banner-wrapper.active .banner-img {
  transform: scale(1);
}

/* 渐变遮罩 - 更自然的渐变效果 */
.gradient-overlay {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  height: 70%;
  background: linear-gradient(
    to bottom,
    transparent,
    rgba(0, 0, 0, 0.2) 40%,
    rgba(0, 0, 0, 0.4)
  );
  pointer-events: none;
}

/* 文本内容动画 */
.banner-content {
  position: absolute;
  bottom: 60rpx;
  left: 50rpx;
  right: 50rpx;
  color: #fff;
  z-index: 1;
  opacity: 0;
  transform: translateY(20rpx);
  transition: all 0.6s ease-out;
}

.banner-content.active {
  opacity: 1;
  transform: translateY(0);
}

.banner-title {
  font-size: 44rpx;
  font-weight: bold;
  margin-bottom: 12rpx;
  display: block;
  text-shadow: 0 4rpx 8rpx rgba(0, 0, 0, 0.3);
  letter-spacing: 2rpx;
}

.banner-desc {
  font-size: 28rpx;
  opacity: 0.95;
  display: block;
  text-shadow: 0 2rpx 4rpx rgba(0, 0, 0, 0.2);
  letter-spacing: 1rpx;
}

/* 自定义指示器样式 */
.custom-indicators {
  position: absolute;
  bottom: 24rpx;
  right: 24rpx;
  display: flex;
  gap: 12rpx;
  padding: 8rpx;
  border-radius: 24rpx;
  background: rgba(0, 0, 0, 0.2);
  backdrop-filter: blur(4px);
}

.indicator-dot {
  width: 36rpx;
  height: 8rpx;
  border-radius: 4rpx;
  background: rgba(255, 255, 255, 0.4);
  cursor: pointer;
  transition: all 0.3s ease;
  overflow: hidden;
}

.indicator-dot.active {
  width: 48rpx;
  background: #fff;
}

.indicator-inner {
  width: 100%;
  height: 100%;
  background: rgba(255, 255, 255, 0.8);
  transform: translateX(-100%);
}

.indicator-dot.active .indicator-inner {
  transform: translateX(0);
  transition: transform 4s linear;
}

/* 适配暗黑模式 */
@media (prefers-color-scheme: dark) {
  .swiper-container {
    box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.25);
  }
}
</style>
